package com.jgdt.jgdtkasannong_university_gene_backend.service.content.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jgdt.jgdtkasannong_university_gene_backend.common.response.PageRequest;
import com.jgdt.jgdtkasannong_university_gene_backend.common.Sysconstant;
import com.jgdt.jgdtkasannong_university_gene_backend.config.enums.SysValueSetEnums;
import com.jgdt.jgdtkasannong_university_gene_backend.entity.content.DataTemplate;
import com.jgdt.jgdtkasannong_university_gene_backend.entity.content.SysMenuBizType;
import com.jgdt.jgdtkasannong_university_gene_backend.enums.content.IsPageEnums;
import com.jgdt.jgdtkasannong_university_gene_backend.mapper.content.SysMenuBizTypeMapper;
import com.jgdt.jgdtkasannong_university_gene_backend.service.content.DataTemplateService;
import com.jgdt.jgdtkasannong_university_gene_backend.service.content.MediaService;
import com.jgdt.jgdtkasannong_university_gene_backend.service.content.MenuContentService;
import com.jgdt.jgdtkasannong_university_gene_backend.service.content.SysMenuService;
import com.jgdt.jgdtkasannong_university_gene_backend.entity.content.SysMenu;
import com.jgdt.jgdtkasannong_university_gene_backend.mapper.content.SysMenuMapper;

import com.jgdt.jgdtkasannong_university_gene_backend.service.sys.SysValueSetService;
import com.jgdt.jgdtkasannong_university_gene_backend.utils.BeanUtils;
import com.jgdt.jgdtkasannong_university_gene_backend.utils.excel.ImageUtils;
import com.jgdt.jgdtkasannong_university_gene_backend.vo.content.menu_content.ChildrenShowVo;
import com.jgdt.jgdtkasannong_university_gene_backend.vo.content.menu_content.ContentGeneralVo;
import com.jgdt.jgdtkasannong_university_gene_backend.vo.content.menu_content.SysMenuBaseVo;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;



/**
 * <p>
 * 系统菜单表 服务实现类
 * </p>
 *
 * @author chenzg
 * @since 2025-04-24
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper,SysMenu> implements SysMenuService {

    @Resource
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private MenuContentService menuContentService;

    @Autowired
    private DataTemplateService dataTemplateService;

    @Autowired
    private SysMenuBizTypeMapper sysMenuBizTypeMapper;

    @Autowired
    private SysValueSetService sysValueSetService;
    @Autowired
    private MediaService mediaService;



    @Override
    public List<SysMenu> getFullTree() {
        List<SysMenu> allMenus = sysMenuMapper.selectList(new QueryWrapper<SysMenu>()
                .orderByAsc("sort_num"));
        return buildTree(allMenus);
    }

    /**
     * 构建树结构核心方法
     * @param menus
     * @return
     */
    private List<SysMenu> buildTree(List<SysMenu> menus) {
        return menus.stream()
                .filter(menu -> menu.getParentId() == null || menu.getParentId() == 0)
                .peek(menu -> setChildren(menu, menus))
                .sorted(Comparator.comparingInt(SysMenu::getSortNum))
                .collect(Collectors.toList());
    }

    /**
     * 递归设置子节点
     * @param parent
     * @param allMenus
     */
    private void setChildren(SysMenu parent, List<SysMenu> allMenus) {
        List<SysMenu> children = allMenus.stream()
                .filter(menu -> parent.getId().equals(menu.getParentId()))
                .peek(menu -> setChildren(menu, allMenus))
                .sorted(Comparator.comparingInt(SysMenu::getSortNum))
                .collect(Collectors.toList());
        parent.setChildren(children);
    }

    @Override
    public List<SysMenu> getChildrenByParentId(Integer parentId) {
        List<SysMenu> allMenus = sysMenuMapper.selectList(null);
        List<SysMenu> result = new ArrayList<>();
        collectChildren(parentId, allMenus, result);
        return result;
    }

    @Override
    public List<ChildrenShowVo> getChildrenBaseVoByParentId(Integer parentId) {
        List<SysMenu> allMenus = sysMenuMapper.selectList(null);
        List<ChildrenShowVo> sysMenuBaseVos= BeanUtils.convertList(allMenus,ChildrenShowVo.class);
        List<ChildrenShowVo> result = new ArrayList<>();
        collectChildrenShowVo(parentId,sysMenuBaseVos, result);
        return result;
    }



    @Override
    public List<SysMenu> querySysMenuList(SysMenu sysMenu) {
        if (ObjectUtils.isEmpty(sysMenu)) {
            return new ArrayList<>();
        }
        QueryWrapper<SysMenu> wrapper = new QueryWrapper<>();
        Integer level = sysMenu.getLevel();
        if (level != null) {
            wrapper.lambda().eq(SysMenu::getLevel, level);
        }
        return sysMenuMapper.selectList(wrapper);
    }

    @Override
    public DataTemplate queryDataTemplateByMenuId(Integer menuId) {
       if(menuId==null){
           return null;
       }
        LambdaQueryWrapper<SysMenu> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(SysMenu::getId,menuId);
        SysMenu sysMenu=sysMenuMapper.selectOne(queryWrapper);
        if(ObjectUtils.isNull(sysMenu) || sysMenu.getTemplateId()==null){
                return null;
        }
        return dataTemplateService.queryDataTemplateByid(sysMenu.getTemplateId());
    }

    @Override
    public SysMenuBizType getBizTypeByMenuId(Integer menuId) {
        SysMenuBizType sysMenuBizType=new SysMenuBizType();
        if(menuId==null){
            return sysMenuBizType;
        }
        LambdaQueryWrapper<SysMenu> sysMenuLambdaQueryWrapper=new LambdaQueryWrapper<>();
        sysMenuLambdaQueryWrapper.eq(SysMenu::getId,menuId);
        SysMenu sysMenu=this.getOne(sysMenuLambdaQueryWrapper);
        if(ObjectUtils.isEmpty(sysMenu)){
            return sysMenuBizType;
        }
        if(sysMenu.getBizTypeId()==null){
            return sysMenuBizType;
        }
        return sysMenuBizTypeMapper.selectById(sysMenu.getBizTypeId());
    }



    /**
     * 递归收集所有子节点
     * @param parentId
     * @param allMenus
     * @param result
     */
    private void collectChildren(Integer parentId, List<SysMenu> allMenus, List<SysMenu> result) {
        allMenus.stream()
                .filter(menu -> parentId.equals(menu.getParentId()))
                .forEach(menu -> {
                    result.add(menu);
                    collectChildren(menu.getId(), allMenus, result);
                });
    }



    /**
     * 递归收集所有子节点
     * @param parentId
     * @param allMenus
     * @param result
     */
    private void collectChildrenShowVo(Integer parentId, List<ChildrenShowVo> allMenus, List<ChildrenShowVo> result) {
        allMenus.stream()
                .filter(menu -> parentId.equals(menu.getParentId()))
                .forEach(menu -> {
                    //内容查询
                    //非分页对象填充
                    SysMenu sysMenu = sysMenuMapper.selectById(menu.getId());
                    if (IsPageEnums.YES.getKey().equals(menu.getIsPage())) {
                        //分页参数对象填充
                        PageRequest<ContentGeneralVo> page=new PageRequest<>();
                        page.setPageNum(Sysconstant.DEFAULT_PAGENUM);
                        Integer pageSize=Integer.parseInt(sysValueSetService.queryPriorityValueByCode(SysValueSetEnums.CONTENT_PAGESIZE.getCode()));
                        page.setPageSize(pageSize);
                        ContentGeneralVo contentGeneralVo=new ContentGeneralVo();
                        page.setCondition(contentGeneralVo);
                        //分页查询
                        IPage<ContentGeneralVo> sysMenuBaseVoIPage= menuContentService.contenShowPage(page,sysMenu.getId());
                        //分页结果对象填充
                        IPage<ContentGeneralVo> iPage=new Page<>(page.getPageNum(),page.getPageSize());
                        iPage.setTotal(sysMenuBaseVoIPage.getTotal());
                        //frontImageUrl 赋值
                        List<ContentGeneralVo> list=BeanUtils.convertList(sysMenuBaseVoIPage.getRecords(),ContentGeneralVo.class);
                        for (ContentGeneralVo vo:list){
                            vo.setFrontImageUrl(mediaService.getImgUrl(vo.getImageUrl()));
                        }
                        iPage.setRecords(list);
                        menu.setContentGeneralVoPage(iPage);
                    } else {
                        List<SysMenuBaseVo> SysMenuBaseVoList = menuContentService.contenShowByMenuId(Arrays.asList(sysMenu));
                        //非分页内容对象赋值
                        if (CollectionUtil.isNotEmpty(SysMenuBaseVoList)) {
                            List<ContentGeneralVo> contentGeneralVos = SysMenuBaseVoList.get(0).getContentGeneralVos();
                            List<ContentGeneralVo> addContentGeneralVos = BeanUtils.convertList(contentGeneralVos, ContentGeneralVo.class);
                            //frontImageUrl 赋值
                            for(ContentGeneralVo vo:addContentGeneralVos){
                                vo.setFrontImageUrl(mediaService.getImgUrl(vo.getImageUrl()));
                            }
                            menu.setContentGeneralVos(addContentGeneralVos);
                        }
                    }
                    collectChildrenShowVo(menu.getId(), allMenus, result);
                    result.add(menu);
                });
    }
}
